// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj

// jsdoc语法提示教程：https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
const db = uniCloud.databaseForJQL()
const dbb = uniCloud.database()
const cmd = db.command

const uniID = require('uni-id-common')
module.exports = {

	_before: async function() { // 通用预处理器
    
		const clientInfo = this.getClientInfo()
		this.uniID = uniID.createInstance({ // 创建uni-id实例，其上方法同uniID
			clientInfo
		})
		

	},

	async getMe() {
      const token=await this.getUniIdToken()
      const res=await this.uniID.checkToken(token)
	return {
		token:token,
		res:res
	}

	},
	/**
	 *@param {Array} fileIds fileIds组成的数组  

	*/
	async deleteFile(fileIds){
		let result=await uniCloud.deleteFile({
			fileList:fileIds
		})
		return result
	},
	
	/**
	 * method1方法描述
	 * @param {string} param1 表名
	 * @param { object} 查询对象
	 * @returns {Array} 查询的结果数级
	 */
	async getDB(dbname, param) {
		// 参数校验，如无参数则不需要
		if (!param) {
			return {
				code: false,
				errMsg: '缺少查询条件'
			}
		}
		try {
			const res = await db.collection(dbname).where(param).get()
			if (res.data.length > 0) {
				return {
					code: true,
					data: res.data
				}
			} else {
				return {
					code: false,
					errMsg: "查询无数据"
				}
			}
		} catch (e) {
			return {
				code: false,
				errMsg: "查询错误" + e
			}
		}
	},
	/**
	 * 更新数据方法说明
	 * @param {string} dbName 数据库名
	 * @param {object} where 查询条件
	 * @param {object} data 更新内容  
	 * @returns {object} 返回值code更新成功true，返回更新数量
	 */

	async updateDB(dbName, where, data) {
		// 完善参数验证
		if (!dbName) {
			return {
				code: false,
				msg: '缺少集合名称(dbName)'
			};
		}
		if (!where || Object.keys(where).length === 0) {
			return {
				code: false,
				msg: '缺少查询条件(where)'
			};
		}
		if (!data || typeof data !== 'object' || Object.keys(data).length === 0) {
			return {
				code: false,
				msg: '缺少更新数据(data)或数据格式不正确'
			};
		}

		try {
			// 使用指定的集合名称
			const r = await db.collection(dbName).where(where).update(data);

			if (r.updated > 0) {
				return {
					code: true,
					msg: `成功更新${r.updated}条记录`,
					data: r.updated
				};
			} else {
				return {
					code: false,
					msg: '没有匹配的数据被更新',
					data: 0
				};
			}
		} catch (e) {
			// 保留原始错误信息便于调试
			console.error('数据库更新失败:', e);
			return {
				code: false,
				msg: '系统错误，更新失败',
				data: e.message || String(e)
			};
		}
	},

	async addDB(DBname, param) {
		try {
			const res = await db.collection(DBname).add(param)
			console.log('------------', res);
			if (res.code === 0) {
				return {
					code: true,
					data: res
				}
			} else {
				return {
					code: false,
					errMsg: "填写数据有误"
				}
			}
		} catch (e) {
			return {
				code: false,
				errMsg: "系统错误" + e
			}
		}
	},
	async getAppForStorageList(userId) {
		try {
			const appIds = await db.collection('ApplyForStorage').where({
				"userId": userId
			}).getTemp()
			const res = await db.collection(appIds, "approval").get()
			if (res.data.length > 0) {
				return {
					code: true,
					data: res.data
				}
			} else {
				return {
					code: false,
					data: "查无数据"
				}
			}

		} catch (e) {
			return {
				code: false,
				data: "查询系统出错",
				err: e
			}

		}
	},
	//验证业务类型（type:wms,ums,operator）
	async loginBussines(uid, type) {
		// 参数验证增强
		if (typeof uid !== 'string' || !uid.trim()) {
			return {
				code: false,
				errMsg: '参数错误：uid必须为非空字符串'
			};
		}

		if (typeof type !== 'string' || !['wms', 'ums','operator'].includes(type)) {
			return {
				code: false,
				errMsg: '参数错误：type必须为wms或ums'
			};
		}

		try {
			// 执行数据库查询
			const {
				data
			} = await db.collection('user').where({
				uid
			}).get();

			// 检查用户是否存在
			if (!data || data.length === 0) {
				return {
					code: false,
					errMsg: '用户不存在'
				};
			}

			const user = data[0];

			// 检查角色是否匹配
			if (!user.role || !user.role.includes(type)) {
				return {
					code: false,
					errMsg: `用户没有${type}业务权限`
				};
			}

			// 登录成功，返回用户数据
			return {
				code: true,
				data: {
					uid: user.uid,
					role: user.role
				}
			};
		} catch (error) {
			console.error(`业务登录验证失败 (uid=${uid}, type=${type}):`, error);
			return {
				code: false,
				errMsg: '系统繁忙，请稍后再试'
			};
		}
	},

	/**
	 * 注册业务账号
	 * @param {string} uid - 用户唯一标识
	 * @param {('wms'|'ums')} type - 业务类型：wms=仓库，ums=货主
	 * @param {Object} form - 业务表单数据
	 * @returns {Promise<{code: boolean, errMsg?: string}>} - 返回注册结果
	 */

	async regBussiness(uid, type, form) {
		const DbName = {
			wms: "warehouse",
			ums: "supplier",
			operator:"operator"
		}

		try {
			// 检查业务类型是否存在
			if (!DbName[type]) {
				return {
					code: false,
					errMsg: `不支持的业务类型: ${type}`
				}
			}

			// 注册业务账号
			const regRes = await dbb.collection(DbName[type]).add(form);
			console.log('注册结果', regRes);

			if (regRes.id) {
				// 更新用户角色
				const writeInUser = await dbb.collection('user').where({
					uid: uid
				}).update({
					role: dbb.command.push([type])
				});

				// 检查更新是否成功
				if (writeInUser.updated >= 1) {
					return {
						code: true,
						message: '注册成功'
					}
				} else {
					return {
						code: false,
						errMsg: '更新用户角色失败',
						detail: writeInUser
					}
				}
			} else {
				return {
					code: false,
					errMsg: '创建业务账号失败',
					detail: regRes
				}
			}
		} catch (e) {
			console.error('注册异常', e);
			return {
				code: false,
				errMsg: '系统错误，请重试',
				detail: e.message
			}
		}
	},
	/**
	 * @param {Object} execlData execl表（处理过的）
	 * @param {Object} DBname 表名称
	 */
	

	async importData(execlData,DBname){
		
		try {
		    const { header, data } = execlData;
		    let successCount = 0;
		    let failCount = 0;
		    
		    // 遍历数据并插入数据库
		    for (const row of data) {
		      try {
		        // 创建数据对象，将表头与数据对应
		        const item = {};
		        header.forEach((key, index) => {
		          item[key] = row[index];
		        });
		        
		        // 插入数据库（以MySQL为例）
		       const res   = await   db.collection(DBname).add(item)
			   if(res.id){
				successCount++;
			
			   }
	
		      } catch (error) {
		        console.error('插入数据失败', error);
		        failCount++;
		      }
		    }

	return {
		code:true,
		successCount:successCount,
		failCount:failCount
	}	
	}catch(e){
			return {
				code:false,
				successCount:successCount,
				failCount:failCount
			}
	}},
	/**
	 * method1方法描述
	 * @param {string} uid 用户uid
	 * @param {string} type 模块类型wms，ums，optorator
	 * 
	 * @returns {object} 所归属的仓库/供应商/运营商信息列表
	 */
	async getOwnership(uid, type) {
		const name = {
			wms: "仓库",
			ums: "货主",
			operator:"运营商"
		}
		const DbName = {
			wms: "warehouse",
			ums: "supplier",
			operator:"operator"
		}

		// 验证type参数是否有效
		if (!DbName[type]) {
			throw new Error(`无效的业务类型: ${type}`);
		}

		try {
			const res = await dbb.collection(DbName[type]).where({
				"user": dbb.command.elemMatch({
					uid: dbb.command.eq(uid)
				}),
	

			}).get();
			if (res.data.length > 0) {
				return {
					code: true,
					data: res.data
				}

			} else {
				return {
					code: false,
					errMsg: `您没有归属的${name[type]}`
				}
			}
		} catch (e) {
			return {
				code: false,
				errMsg: e
			}
		}
	},

	/**
	 * method1方法描述
	 * @param {string} supplierId 货主id
	 * @param {string} wareHouseId 仓库id
	 * @returns {object} 所归属的仓库/供应商/运营商信息列表
	 */
	async applyForNewWareHouse(supplierId, wareHouseId, warehouse_name) {
		try {
			// 关键修复1：统一字段名
			const fieldName = "warehouse";

			// 关键修复2：用elemMatch查询数组中是否有对象的code等于wareHouseId
			const {
				data
			} = await dbb.collection('supplier').where({
				code: supplierId,
				[fieldName]: dbb.command.elemMatch({
					code: wareHouseId
				})
			}).get();
			console.log("检查申请状态打印", JSON.stringify(data));
			// 如果已存在关联记录
			if (data && data.length > 0) {
				console.log('该供应商已关联此仓库');
				return {
					code: false,
					errMsg: '您已经申请过该仓库'
				};
			} else {
				const status = "已申请";
				// 更新时使用正确的字段名
				const res = await dbb.collection('supplier').where({
					code: supplierId
				}).update({
					[fieldName]: dbb.command.push({
						code: wareHouseId,
						status: status,
						warehouse_name: warehouse_name
					})
				});

				console.log("申请仓库状态打印", res);
				if (res.updated === 0) {
					return {
						code: false,
						errMsg: '已申请'
					}
				} else {
					return {
						code: true,
						errMsg: "申请成功"
					}

				}

			}
		} catch (e) {
			return {
				code: false,
				errMsg: '系统错误：' + e.message
			};
		}
	},

	async inventoryCheck(data) {

		try {
			const getres = await db.collection('inventory_check_result').where(
				'acceptItemId==data.acceptItemId').get()
			if (getres.data.length === 0) {
				const add = await db.collection('inventory_check_result').add(data)
			
				if (add.id) {
					const up = await db.collection('ApplyForGoodDetail').where({
						_id: data.acceptItemId
					}).update({
						CheckDetailId: add.id
					})
			
					return {
						code: true,
						errMsg: "添加成功"
					}
				}
			} else {
				const updata = await db.collection('inventory_check_result').where({
					acceptItemId: data.acceptItemId
				}).update(data)
				if (updata.updated > 0) {
					return {
						code: true,
						errMsg: "更新成功"
					}
				}
			}
		} catch (e) {
			console.error(e);
			return {
				code: false,
				errMsg: "系统繁忙稍侯再试"
			}
		}

	},
	/**
	 * @param {string} id  'ApplyForGoodDetail'里的_id申请单号Id
	 * @return {Array} data包含的验收明细

	
	*/
	async getApplyForGoodDetail(id) {
		try {
			const r = await db.collection('ApplyForGoodDetail').where({
				applyForId: id
			}).getTemp()
			const c = await db.collection(r, 'inventory_check_result').get()
			if (c.data.length > 0) {
				return {
					code: true,
					data: c.data
				}
			}


		} catch (e) {
			return {
				code: false,
			}

		}
	},
	/**
	 * @param {object} parmas 查询库存的条件 
	 * @returns {Array} 
	 * 
	 */
	async getInentory(parmas) {
		let where = {
			...parmas

		}
		try {
			const resa = await db.collection('inventory').where(where).getTemp()
			const resb = await db.collection(resa, 'product').get()
			if (resb.data.length > 0) {
				return {
					code: true,
					data: resb.data
				}
			}
		} catch (e) {
			return {
				code: false,
				errMsg: e

			}
		}

	},
	/**
	 * @param {Object} params normal正常数量，abnormal缺陷数量
	 * @param {Object} action 动作加减，动作来源单据
	 * 
	 */

	async onInventoryFlow(mainBody, productInfo, action) {
		// 1. 定义唯一标识字段（用于确定一个唯一的库存项）
		// 这些字段组合起来唯一标识一个商品的库存（如：仓库+供应商+商品+批次等）
		const uniqueFields = {
			wareHouseId: mainBody.wareHouseId,
			supplierId: mainBody.supplierId,
			productionCode: productInfo.productionCode,
			productId: productInfo.productId,
			spec: JSON.stringify(productInfo.spec), // 规格（数组需保证完全匹配）
			checkType: productInfo.checkType.type,
			productionDate: productInfo.productionDate,
			batchNo: productInfo.batchNo,
			locationNo: productInfo.locationNo
		};

		try {
			// 2. 查询最新流水记录，计算当前库存
			const queryResult = await db.collection('inventoryFlow')
				.where(uniqueFields)
				.orderBy('updatedAt', 'desc')
				.limit(1)
				.get();

			const latestInventory = queryResult.data[0] || null;
			const currentTotalQuantity = latestInventory ? latestInventory.lastQuantity : 0;

			// 3. 计算新库存（本次变动后）
			let newTotalQuantity;
			if (action.type === 'add') {
				newTotalQuantity = currentTotalQuantity + (productInfo.convertedQuantity || 0);
			} else {
				newTotalQuantity = Math.max(0, currentTotalQuantity - (productInfo.convertedQuantity || 0));
			}

			// 4. 新增流水记录（保留历史）
			const flowRecord = {
				...uniqueFields, // 继承唯一标识字段
				action: action, // 操作类型（add/减少）
				quantity: productInfo.convertedQuantity || 0, // 本次变动数量
				previousQuantity: currentTotalQuantity, // 操作前库存
				lastQuantity: newTotalQuantity, // 操作后库存
				updatedAt: new Date() // 流水创建时间
			};
			const addFlowRes = await db.collection('inventoryFlow').add(flowRecord);

			// 5. 同步更新库存状态表（核心：形成当前库存表）
			// 5.1 定义库存表的查询条件（与唯一标识一致）
			const inventoryWhere = {
				...uniqueFields
			};

			// 5.2 准备库存表的更新数据
			const inventoryData = {
				...uniqueFields, // 存储唯一标识字段（用于查询和关联）
				currentQuantity: newTotalQuantity, // 当前最新库存
				lastFlowId: addFlowRes.id, // 关联最新流水记录ID（便于追溯）
				lastUpdated: new Date() // 最后更新时间
			};

			// 5.3 执行 upsert 操作（有则更新，无则插入）
			// 先尝试更新
		
			const updateRes = await db.collection('inventory')
				.where(inventoryWhere)
				.update({
					currentQuantity: newTotalQuantity,
					lastFlowId: addFlowRes.id,
					lastUpdated: new Date()
				});

			// 如果没有找到记录（更新行数为0），则插入新记录
			if (updateRes.updated === 0) {
				await db.collection('inventory').add(inventoryData);
			}

			// 6. 返回结果（包含流水和库存表信息）
			return {
				success: true,
				message: '库存流水和库存表已同步更新',
				data: {
					flow: {
						...flowRecord,
						_id: addFlowRes.id
					}, // 流水记录
					inventory: {
						...inventoryData,
						_id: updateRes.updated > 0 ? null : '新插入'
					} // 库存状态
				}
			};

		} catch (e) {
			console.error('库存操作失败：', e);
			return {
				success: false,
				message: `操作失败：${e.message}`,
				error: e
			};
		}
	},


	// 云对象方法定义
	async exportInventoryData(data) {
		const {
			exportData,
			filterParams,
			renderType
		} = data

		// 1. 处理对象结构转换（去嵌套）
		const flatData = flattenInventoryData(exportData)

		// 2. 生成Excel文件
		const excelBuffer = await generateExcel(flatData, renderType)

		// 3. 上传文件到云存储
		const uploadResult = await uploadToCloudStorage(excelBuffer)

		// 4. 返回下载链接
		return {
			downloadUrl: uploadResult.fileURL,
			expireAt: Date.now() + 3600 * 1000 // 1小时后过期
		}
	
}
	// 处理嵌套对象结构，转为扁平结构
}	

	



 function flattenInventoryData(rawData){
		return rawData.map(item => {
			// 处理productId嵌套对象
			let productId = ''
			let productName = ''
			let productBarcode = ''
			let productUnit = ''

			if (item.productId && item.productId.length > 0) {
				const product = item.productId[0]
				productId = product._id || ''

				// 提取商品名称
				if (product.goodName && product.goodName.length > 0) {
					productName = product.goodName[0].goodName || ''
				}

				// 提取条形码
				if (product.barcode && product.barcode.length > 0) {
					productBarcode = product.barcode[0] || ''
				}

				// 提取单位信息
				if (product.unit && product.unit.length > 0) {
					productUnit = product.unit[0].unitName || ''
				}
			}

			// 处理规格信息
			let specInfo = ''
			try {
				const specObj = JSON.parse(item.spec || '{}')
				specInfo = specObj.spceStr || specObj.specStr || ''
			} catch (e) {
				specInfo = item.spec || ''
			}

			// 返回扁平结构
			return {
				序号: item._id || '',
				商品名称: item.商品名称 || productName,
				产品ID: item.产品ID || productId,
				规格: specInfo,
				单位: productUnit,
				条形码: productBarcode,
				产品状态: item.产品状态 || getCheckTypeText(item.checkType),
				批次号: item.批次号 || item.batchNo || '',
				一物一码: item.一物一码 || item.productionCode || '',
				生产日期: item.生产日期 || formatDate(item.productionDate),
				库存数量: item.库存数量 || item.currentQuantity || 0,
				最后更新时间: item.最后更新时间 || formatDate(item.lastUpdated),
				操作流水: item.lastFlowId || ''
			}
		})
	}

	// 生成Excel文件
async  function	generateExcel(data, renderType) {
		const xlsx = require('xlsx')

		// 创建工作簿和工作表
		const workbook = xlsx.utils.book_new()
		const worksheet = xlsx.utils.json_to_sheet(data)

		// 根据渲染类型设置工作表名称
		const sheetName = {
			'productTotal': '产品合计',
			'batchDetail': '批次明细',
			'productionCodeDetail': '一物一码明细'
		} [renderType] || '库存数据'

		xlsx.utils.book_append_sheet(workbook, worksheet, sheetName)

		// 转换为Buffer
		return xlsx.write(workbook, {
			type: 'buffer',
			bookType: 'xlsx'
		})
	}

	// 上传到云存储
	async function uploadToCloudStorage (buffer) {
	
	

		// 生成唯一文件名
		const fileName = `inventory-export/${Date.now()}.xlsx`

		// 上传文件
		return await uniCloud.uploadFile({
			cloudPath: fileName,
			fileContent: buffer
		})
	}

	// 辅助方法：格式化日期
function	formatDate(dateStr) {
		if (!dateStr) return ''
		if (typeof dateStr === 'string' && dateStr.length === 8) {
			return `${dateStr.slice(0,4)}-${dateStr.slice(4,6)}-${dateStr.slice(6,8)}`
		}
		const date = new Date(dateStr)
		return date.toLocaleDateString()
	}

	// 辅助方法：获取状态文本
function	getCheckTypeText(type) {
		const map = {
			normal: '正常',
			invalidDate: '无效日期',
			breakage: '破损沾污',
			invalidBatch: '无效批次',
			invalidEncoding: '无效编码'
		}
		return map[type] || '未知'
	}

	// 云对象权限控制
function	_getPermission(){
		return {
			// 允许所有登录用户调用
			'exportInventoryData': {
				permission: true
			}
		}
}